State Pattern

State Pattern ကတော့ Behaviour Pattern တစ်ခုပါ။ State Pattern ကတော့ strategy pattern နဲ့ တူသလို နဲ့ မှားတတ်ပါတယ်။ State Pattern ကတော့ strategy pattern လိုပါပဲ။ ဒါပေမယ့် သူက state တစ်ခု ကနေ တစ်ခု ပြောင်းလဲ သွားတာ ရှိပါတယ်။

မီးပွိုင့်တွေ မှာ ဆိုရင် ရှိသည့် state တွေက မီးရောင်က အနီ ၊​ အဝါ၊ အစိမ်း ဆိုပြီး ရှိပါမယ်။ အနီ ပြီးရင် စိမ်းမယ်။ အစိမ်းပြီးရင် ဝါမယ်။ အဝါပြီးရင် အနီ ပြောင်းမယ်။ တနည်းပြောရင် state တစ်ခု ကနေ တစ်ခု ပြောင်းသွားသည့် သဘောပါပဲ။

ပုံမှန် ရေးမယ် ဆိုရင် if else condition တွေ နဲ့ ရေးရပါမယ်။

public class Main {
    static String currentState = "Red";

    public static void main(String[] args) {
        changeState();
        processFunction();
        System.out.println(currentState);
    }

    static void changeState() {
        if (currentState.equals("Red")) {
            currentState = "Green";
        } else if (currentState.equals("Green")) {
            currentState = "Yellow";
        } else if (currentState.equals("Yellow")) {
            currentState = "Red";
        }
    }

    static void processFunction() {
        if (currentState.equals("Red")) {
            System.out.println("Stop the car");
        } else if (currentState.equals("Green")) {
            System.out.println("Allow to go");
        } else if (currentState.equals("Yellow")) {
            System.out.println("Slow down");
        }
    }
}

အကယ်၍ State တွေ များလာပြီဆိုရင် If else conditoin တွေ များလာပါပြီ။ နောက်ပြီး Code က Single Responbiltiy မရှိတော့ပါဘူး။ ဥပမာ Red State မှာ လုပ်မယ့် အတွက် ဒီ function ထဲမှာ if else တွေ နဲ့ စစ်ပြီး ရေးသားနေရသည့် အတွက် code က open/closed principle ကို မလိုက်နာတော့ပါဘူး။​

State Pattern မှာ State Interface ရှိပြီး State တွေက interface ကို implement လုပ်ထားသည့် သဘောပါပဲ။

State မှာ အဆင့် တစ်ခု ကနေ နောက် တဆင့် ကို ပြောင်းသွားသည့် သဘောမျိုး တွေ မှာ အသုံးပြုပါတယ်။

LightState.java

interface LightState {
  void change(TrafficLight light);
  String getColor();
  void process();
}

RedLightState.java 

class RedLightState implements LightState {
  @Override
  public void change(TrafficLight light) {
    light.setState(new YellowLightState());
  }

  @Override
  public String getColor() {
    return "Red";
  }

  @Override
  public void process() {
   System.out.print("Stop the car");
  }
}

YellowLightState.java

class YellowLightState implements LightState {
  @Override
  public void change(TrafficLight light) {
    light.setState(new GreenLightState());
  }

  @Override
  public String getColor() {
    return "Yellow";
  }

  @Override
  public void process() {
   System.out.print("Slown down");
  }
}

GreenLightState.java

class GreenLightState implements LightState {
  @Override
  public void change(TrafficLight light) {
    light.setState(new RedLightState());
  }

  @Override
  public String getColor() {
    return "Green";
  }

  @Override
  public void process() {
   System.out.print("Allow to go");
  }
}

TrafficLight.java

public class TrafficLight {
  private LightState currentState;

  public TrafficLight() {
    this.currentState = new RedLightState();
  }

  public void changeState() {
    currentState.change(this);
  }

  public void process() {
     currentState.process();
  }
  public String getCurrentColor() {
    return currentState.getColor();
  }

  public void setState(LightState state) {
    this.currentState = state;
  }
}

**

Main.java**

public class Main {
    public static void main(String[] args) {
        TrafficLight trafficlight = new TrafficLight()
        System.out.print(trafficelight.getCurrentColor());
        trafficelight.process();
        trafficelight.changeState();
        System.out.print(trafficelight.getCurrentColor());
        trafficelight.process();
    }
}

Pros and Cons

Single Responsibility ကို လိုက်နာထားပါတယ်။ State တစ်ခုဟာ သူ့ သက်ဆိုင်ရာ အလုပ်ပဲ လုပ်ပါတယ်။

Open/Closed Principle ကို လိုက်နာထားပါတယ်။ State တစ်ခု ကို ထပ်ဖြည့်ဖို့ လက်ရှိ code အဟောင်းကို ပြင်ဖို့ မလိုပါဘူး။

မကောင်းတာကတော့ state နည်းနည်းလေးပဲ ရှိသည့် အခါမှာတော့ over kill ဖြစ်နိုင်ပါတယ်။